package com.salton123.voice.player;

import android.annotation.SuppressLint;
import android.app.Application;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;


/**
 * User: newSalton@outlook.com
 * Date: 2019/3/8 19:07
 * ModifyTime: 19:07
 * Description:
 */

public class AudioPlayerHelper implements IAudioPlayer,
        MediaPlayer.OnPreparedListener,
        MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnInfoListener,
        MediaPlayer.OnSeekCompleteListener,
        MediaPlayer.OnCompletionListener,
        MediaPlayer.OnErrorListener {
    private static AudioPlayerHelper mInstance;
    private static final int TYPE_UPDATE_PROGRESS_MESSAGE = 0x101;
    private static final long UPDATE_PROGRESS_DEFAULT_INTERVAL = 100;

    public static AudioPlayerHelper getInstance() {
        if (mInstance == null) {
            synchronized (AudioPlayerHelper.class) {
                if (mInstance == null) {
                    mInstance = new AudioPlayerHelper();
                }
            }
        }
        return mInstance;
    }

    private MediaPlayer mMediaPlayer;
    private static final String TAG = "AudioPlayerHelper";
    /**
     * 播放器当前状态
     */
    private int mState = 0;
    private Application mApplication;
    @SuppressLint("HandlerLeak")
    private Handler mMessageHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case TYPE_UPDATE_PROGRESS_MESSAGE:
                    onUpdateProgress();
                    break;
            }
        }
    };
    private String mDataSource;
    private int mStartPosition = 0;
    private OnPlayerStateChangeListener mListener;

    public void setOnPlayerStateChangeListener(OnPlayerStateChangeListener listener) {
        this.mListener = listener;
    }

    public AudioPlayerHelper init(Application application) {
        this.mApplication = application;
        return this;
    }

    @Override
    public AudioPlayerHelper path(String dataSource) {
        this.mDataSource = dataSource;
        return this;
    }

    public AudioPlayerHelper setStartPosition(int startPosition) {
        this.mStartPosition = startPosition;
        return this;
    }

    @Override
    public AudioPlayerHelper start() {
        if (TextUtils.isEmpty(this.mDataSource)) {
            Log.i(TAG, "[playMusic] invalid musicPlayPath = " + mDataSource);
            if (mListener != null) {
                mListener.onError("invalid musicPlayPath == null", mDataSource + "");
            }
        } else {
            try {
                mState = PlayerState.STATE_IDLE;
                if (mMediaPlayer == null) {
                    mMediaPlayer = new MediaPlayer();
                    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    mMediaPlayer.setOnPreparedListener(this);
                    mMediaPlayer.setOnBufferingUpdateListener(this);
                    mMediaPlayer.setOnInfoListener(this);
                    mMediaPlayer.setOnSeekCompleteListener(this);
                    mMediaPlayer.setOnCompletionListener(this);
                    mMediaPlayer.setOnErrorListener(this);
                }
                mMediaPlayer.reset(); //把各项参数恢复到初始状态
                //待补充对各种Uri的判断，调用对应的setDataSource重载函数
                Uri uri = Uri.parse(mDataSource);
                if (UriUtil.isLocalAssetUri(uri)) {
                    // mMediaPlayer.setDataSource();
                } else if (UriUtil.isNetworkUri(uri)) {

                } else if (UriUtil.isLocalFileUri(uri)) {

                }
                mState = PlayerState.STATE_PREPARING;
                mMediaPlayer.setDataSource(mApplication, uri);
                mMediaPlayer.prepareAsync();  //进行缓冲
                if (mListener != null) {
                    mListener.onPreparing(mDataSource);
                }
                // mMediaPlayer.start();
            } catch (Throwable e) {
                Log.i(TAG, "playMusic exception = " + e);
                if (mListener != null) {
                    mListener.onError("init player error,ex:" + e.getLocalizedMessage(),
                            mDataSource + "");
                }
            }
            onUpdateProgress();
        }
        return this;
    }

    @Override
    public AudioPlayerHelper pause() {
        if (mState == PlayerState.STATE_PLAYING) {
            mState = PlayerState.STATE_PAUSED;
            mMediaPlayer.pause();
            if (mListener != null) {
                mListener.onPause(mDataSource);
            }
        }
        return this;
    }

    @Override
    public AudioPlayerHelper resume() {
        if (mState == PlayerState.STATE_PAUSED) {
            mState = PlayerState.STATE_PLAYING;
            mMediaPlayer.start();
            if (mListener != null) {
                mListener.onPlaying(mDataSource);
            }
            onUpdateProgress();
        }
        return this;
    }

    @Override
    public AudioPlayerHelper stop() {
        if (mState == PlayerState.STATE_PLAYING ||
                mState == PlayerState.STATE_PAUSED ||
                mState == PlayerState.STATE_PREPARED) {
            mState = PlayerState.STATE_STOP;
            mMediaPlayer.stop();
            if (mListener != null) {
                mListener.onStop(mDataSource);
            }
        }
        return this;
    }

    @Override
    public AudioPlayerHelper seekTo(int duration) {
        if (mState == PlayerState.STATE_PLAYING ||
                mState == PlayerState.STATE_PAUSED ||
                mState == PlayerState.STATE_PREPARED) {
            mState = PlayerState.STATE_PLAYING;
            mMediaPlayer.seekTo(duration);
            if (mListener != null) {
                mListener.onSeeking(duration, mDataSource);
            }
        }
        return this;
    }

    @Override
    public AudioPlayerHelper release() {
        stop();
        if (mState == PlayerState.STATE_STOP ||
                mState == PlayerState.STATE_IDLE ||
                mState == PlayerState.STATE_COMPLETED) {
            if (mMediaPlayer != null) {
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
        mState = PlayerState.STATE_RELEASE;
        if (mListener != null) {
            mListener.onRelease(mDataSource);
        }
        return this;
    }

    /**
     * 发送更新播放进度的消息
     */
    private void onUpdateProgress() {
        if (mState == PlayerState.STATE_PLAYING) {
            if (mListener != null) {
                mListener.onProgress(mMediaPlayer.getCurrentPosition(), mDataSource);
            }
            mMessageHandler.sendEmptyMessageDelayed(TYPE_UPDATE_PROGRESS_MESSAGE, UPDATE_PROGRESS_DEFAULT_INTERVAL);
        } else {
            mMessageHandler.removeMessages(TYPE_UPDATE_PROGRESS_MESSAGE);
        }
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        if (mListener != null) {
            mListener.onBufferingUpdate(percent, mDataSource);
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        mState = PlayerState.STATE_COMPLETED;
        if (mListener != null) {
            mListener.onCompletion(mDataSource);
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mState = PlayerState.STATE_ERROR;
        if (mListener != null) {
            mListener.onError("errorCode,what:" + what + ",extra:" + extra, mDataSource);
        }
        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mState = PlayerState.STATE_PREPARED;
        if (mListener != null) {
            mListener.onGetMaxDuration(mp.getDuration(), mDataSource);
        }
        mp.start();
        mState = PlayerState.STATE_PLAYING;
        if (mListener != null) {
            mListener.onPlaying(mDataSource);
        }
        onUpdateProgress();
        if (mStartPosition > 0) {
            mState = PlayerState.STATE_PREPARING;
            mp.seekTo(mStartPosition);
            mStartPosition = 0;
        }
    }

    @Override
    public void onSeekComplete(MediaPlayer mp) {
        mState = PlayerState.STATE_PLAYING;
        if (mListener != null) {
            mListener.onPlaying(mDataSource);
        }
        onUpdateProgress();
    }

    public boolean isPlaying() {
        return mState == PlayerState.STATE_PLAYING;
    }

    /**
     * 播放器状态变化回调
     */
    public interface OnPlayerStateChangeListener {
        void onPreparing(String dataSource);

        void onPlaying(String dataSource);

        void onPause(String dataSource);

        void onCompletion(String dataSource);

        void onStop(String dataSource);

        void onError(String msg, String dataSource);

        void onRelease(String dataSource);

        void onGetMaxDuration(int maxDuration, String dataSource);

        void onProgress(int progress, String dataSource);

        void onSeeking(int duration, String dataSource);

        void onBufferingUpdate(int percent, String dataSource);

    }
}